﻿using System;
using System.ComponentModel;
using System.Data;
using System.Globalization;
using YanZhiwei.DotNet2.Utilities.Enums;
namespace YanZhiwei.DotNet2.Utilities.Common
{
    /// <summary>
    /// 转换帮助类
    /// </summary>
    public static class ConvertHelper
    {
        #region 各进制数间转换
        /// <summary>
        /// 二，八，十，十六进制互相转换
        /// 说明：
        /// 若转换成二进制，会补足八个长度
        /// </summary>
        /// <param name="data">需要转换的字符串</param>
        /// <param name="from">原始进制</param>
        /// <param name="to">目标进制</param>
        /// <returns>转换结果；若转换失败返回"0"</returns>
        public static string ToHexBinDecOct(this string data, Conversion from, Conversion to)
        {
            try
            {
                int _intValue = Convert.ToInt32(data, (int)from);  //十进制
                string _targetValue = Convert.ToString(_intValue, (int)to);  //目标进制
                if (to == Conversion.Binary)
                    _targetValue = StringHelper.ComplementLeftZero(_targetValue, 8);
                return _targetValue;
            }
            catch
            {
                return "0";
            }
        }
        #endregion
        #region 转换成Int类型
        /// <summary>
        /// 转换成Int类型
        /// </summary>
        /// <param name="data">需要转换的object</param>
        /// <param name="errorData">转换失败后返回类型</param>
        /// <returns>转换返回</returns>
        public static int ToInt(this object data, int errorData)
        {
            if (data == null) return errorData;
            int _parseIntValue = 0;
            bool _parseResult = int.TryParse(data.ToString(), out _parseIntValue);
            return _parseResult == true ? _parseIntValue : errorData;
        }
        #endregion
        #region 转换成Int16类型
        /// <summary>
        /// 转换成Int16类型
        /// </summary>
        /// <param name="data">需要转换的object</param>
        /// <param name="errorData">转换失败后返回类型</param>
        /// <returns>转换返回</returns>
        public static Int16 ToInt16(this object data, Int16 errorData)
        {
            if (data == null) return errorData;
            Int16 _parseIntValue = 0;
            bool _parseResult = Int16.TryParse(data.ToString(), out _parseIntValue);
            return _parseResult == true ? _parseIntValue : errorData;
        }
        #endregion
        #region 转换成Int64类型
        /// <summary>
        /// 转换成Int64类型
        /// </summary>
        /// <param name="data">需要转换的object</param>
        /// <param name="errorValue">转换失败后返回类型</param>
        /// <returns>转换返回</returns>
        public static Int64 ToInt64(this object data, Int64 errorValue)
        {
            if (data == null) return errorValue;
            Int64 _parseIntValue = 0;
            bool _parseResult = Int64.TryParse(data.ToString(), out _parseIntValue);
            return _parseResult == true ? _parseIntValue : errorValue;
        }
        #endregion
        #region 转换成Int32类型
        /// <summary>
        /// 转换成Int32类型
        /// </summary>
        /// <param name="data">需要转换的object</param>
        /// <param name="errorValue">转换失败后返回类型</param>
        /// <returns>转换返回</returns>
        public static Int32 ToInt32(this object data, Int32 errorValue)
        {
            if (data == null) return errorValue;
            Int32 _parseIntValue = 0;
            bool _parseResult = Int32.TryParse(data.ToString(), out _parseIntValue);
            return _parseResult == true ? _parseIntValue : errorValue;
        }
        #endregion
        #region 转换成double类型
        /// <summary>
        ///转换成double类型
        /// </summary>
        /// <param name="data">需要转换的object</param>
        /// <param name="errorValue">转换失败后返回类型</param>
        /// <returns>转换返回</returns>
        public static double ToDouble(this object data, double errorValue)
        {
            if (data == null) return errorValue;
            double _parseIntValue = 0;
            bool _parseResult = double.TryParse(data.ToString(), out _parseIntValue);
            return _parseResult == true ? _parseIntValue : errorValue;
        }
        #endregion
        #region 转换成decimal类型
        /// <summary>
        ///  转换成decimal类型
        /// </summary>
        /// <param name="data">需要转换的object</param>
        /// <param name="errorValue">转换失败后返回类型</param>
        /// <returns>转换返回</returns>
        public static decimal ToDecimal(this object data, decimal errorValue)
        {
            if (data == null) return errorValue;
            decimal _parsedecimalValue = 0;
            bool _parseResult = decimal.TryParse(data.ToString(), out _parsedecimalValue);
            return _parseResult == true ? _parsedecimalValue : errorValue;
        }
        #endregion
        #region 转换成string类型
        /// <summary>
        /// 转换成string类型
        /// </summary>
        /// <param name="data">需要转换的object</param>
        /// <param name="errorValue">转换失败后返回类型</param>
        /// <returns>转换返回</returns>
        public static string ToString(this object data, string errorValue)
        {
            return data == null ? errorValue : data.ToString();
        }
        #endregion
        #region 字符串类型转换
        /// <summary>
        /// 字符串类型转换
        /// </summary>
        /// <typeparam name="T">目标类型</typeparam>
        /// <param name="data">需要转换的字符串</param>
        /// <returns>转换类型</returns>
        public static T ToStringBase<T>(this string data)
        {
            T _result = default(T);
            if (!string.IsNullOrEmpty(data))
            {
                TypeConverter _convert = TypeDescriptor.GetConverter(typeof(T));
                _result = (T)_convert.ConvertFrom(data);
            }
            return _result;
        }
        #endregion
        #region 转换成日期
        /// <summary>
        /// 转换成日期
        /// </summary>
        /// <param name="data">数据</param>
        /// <param name="errorValue">转换失败返回数据</param>
        /// <returns></returns>
        public static DateTime ToDate(this object data, DateTime errorValue)
        {
            if (data == null)
                return errorValue;
            DateTime _result;
            return DateTime.TryParse(data.ToString(), out _result) ? _result : errorValue;
        }
        #endregion
        //#region 将实体类转换成字符串【属性之间换行】
        ///// <summary>
        ///// 将实体类转换成字符串【属性之间换行】
        ///// </summary>
        ///// <typeparam name="T">实体类类型</typeparam>
        ///// <param name="entity">实体类</param>
        ///// <param name="propDelimiter">属性与属性之间分隔符</param>
        ///// <param name="propValDelimiter">属性与值之间分隔符</param>
        ///// <returns>字符串</returns>
        //public static string ToString<T>(this T entity, string propDelimiter, string propValDelimiter) where T : class
        //{
        //    if (entity == null)
        //    {
        //        return string.Empty;
        //    }
        //    Type _curType = entity.GetType();
        //    StringBuilder _builder = new StringBuilder(_curType.Name);
        //    _builder.Append(propValDelimiter);
        //    foreach (PropertyInfo property in _curType.GetProperties())
        //    {
        //        if (property.CanWrite && property.CanRead)
        //        {
        //            object _val = property.GetValue(entity, null);
        //            _builder.Append(property.Name);
        //            _builder.Append(propDelimiter);
        //            _builder.Append(_val == null ? "[NULL]" : _val.ToString());
        //            _builder.Append(propValDelimiter);
        //        }
        //    }
        //    return _builder.ToString();
        //}
        ///// <summary>
        ///// 将实体类转换成字符串【属性之间换行】
        ///// </summary>
        ///// <typeparam name="T">实体类类型</typeparam>
        ///// <param name="entity">实体类</param>
        ///// <param name="propValDelimiter">属性与值之间分隔符</param>
        ///// <returns>字符串</returns>
        //public static string ToString<T>(this T entity, string propValDelimiter) where T : class
        //{
        //    return ToString<T>(entity, Environment.NewLine, propValDelimiter);
        //}
        //#endregion
        //#region 将实体类转换成字符串
        ///// <summary>
        ///// 将实体类转换成字符串
        ///// </summary>
        ///// <typeparam name="T">实体类类型</typeparam>
        ///// <param name="entity">实体类</param>
        ///// <returns>字符串</returns>
        //public static string ToString<T>(this T entity) where T : class
        //{
        //    return ToString<T>(entity, ":", string.Empty);
        //}
        //#endregion
        #region 泛型数组转换为字符串
        /// <summary>
        /// 泛型数组转换为字符串
        /// </summary>
        /// <typeparam name="T">泛型</typeparam>
        /// <param name="array">泛型数组</param>
        /// <param name="delimiter">分隔符</param>
        /// <returns>转换好的字符串</returns>
        public static string ToString<T>(this T[] array, string delimiter)
        {
            string[] _array = Array.ConvertAll<T, string>(array, n => n.ToString());
            return string.Join(delimiter, _array);
        }
        #endregion
        #region 将阿拉伯数字转换成中文月份数字
        /// <summary>
        /// 将阿拉伯数字转换成中文月份数字
        /// <para>eg:ConvertHelper.ToChineseMonth(1)==> "一"</para>
        /// </summary>
        /// <param name="data">范围1～12</param>
        /// <returns>超出范围则返回‘’</returns>
        public static string ToChineseMonth(this int data)
        {
            if (!(data == 0 || data > 12))
            {
                string[] _months = { "〇", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二" };
                return _months[data];
            }
            return string.Empty;
        }
        #endregion
        #region 将阿拉伯数字转换成中文日期数字
        /// <summary>
        /// 将阿拉伯数字转换成中文日期数字
        /// </summary>
        /// <param name="data">范围1～31</param>
        /// <returns>超出范围则返回‘’</returns>
        public static string ToChineseDay(int data)
        {
            if (data == 0 || data > 32) return string.Empty;
            string[] _days = {
                           "〇", "一", "二", "三", "四", "五", "六", "七", "八", "九",
                           "十", "十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八", "十九",
                           "廿十", "廿一", "廿二", "廿三", "廿四", "廿五", "廿六", "廿七", "廿八", "廿九",
                           "三十", "三十一"
                       };
            return _days[data];
        }
        #endregion
        #region 转换为农历年
        /// <summary>
        /// 转换为农历年
        /// </summary>
        /// <param name="date">日期</param>
        /// <returns>农历年</returns>
        public static string ToChineseDate(this DateTime date)
        {
            var _cnDate = new ChineseLunisolarCalendar();
            string[] _months = { "", "正月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "冬月", "腊月" };
            string[] _days = { "", "初一", "初二", "初三", "初四", "初五", "初六", "初七", "初八", "初九", "初十", "十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八", "十九", "廿一", "廿二", "廿三", "廿四", "廿五", "廿六", "廿七", "廿八", "廿九", "三十" };
            string[] _years = { "", "甲子", "乙丑", "丙寅", "丁卯", "戊辰", "己巳", "庚午", "辛未", "壬申", "癸酉", "甲戌", "乙亥", "丙子", "丁丑", "戊寅", "己卯", "庚辰", "辛己", "壬午", "癸未", "甲申", "乙酉", "丙戌", "丁亥", "戊子", "己丑", "庚寅", "辛卯", "壬辰", "癸巳", "甲午", "乙未", "丙申", "丁酉", "戊戌", "己亥", "庚子", "辛丑", "壬寅", "癸丑", "甲辰", "乙巳", "丙午", "丁未", "戊申", "己酉", "庚戌", "辛亥", "壬子", "癸丑", "甲寅", "乙卯", "丙辰", "丁巳", "戊午", "己未", "庚申", "辛酉", "壬戌", "癸亥" };
            int _year = _cnDate.GetYear(date);
            string year_cn = _years[_cnDate.GetSexagenaryYear(date)];
            int _month = _cnDate.GetMonth(date);
            int _day = _cnDate.GetDayOfMonth(date);
            //获取第几个月是闰月,等于0表示本年无闰月
            int _leapMonth = _cnDate.GetLeapMonth(_year);
            string _month_cn = _months[_month];
            //如果今年有闰月   
            if (_leapMonth > 0)
            {
                //闰月数等于当前月份   
                _month_cn = _month == _leapMonth ? string.Format("闰{0}", _months[_month - 1]) : _month_cn;
                _month_cn = _month > _leapMonth ? _months[_month - 1] : _month_cn;
            }
            return string.Format("{0}年{1}{2}", year_cn, _month_cn, _days[_day]);
        }
        #endregion
        //#region IDataReader判断转换，若字段值Convert.IsDBNull条件成立，则返回errorData
        ///// <summary>
        ///// IDataReader判断转换，若字段值Convert.IsDBNull条件成立，则返回errorData
        ///// <para>eg:reader.CaseTo<string>("objID", string.Empty);</para>
        ///// </summary>
        ///// <param name="data">IDataReader</param>
        ///// <param name="fieldName">字段名称</param>
        ///// <param name="errorData">转换失败，返回值</param>
        ///// <returns>返回值</returns>
        //public static T CaseTo<T>(this IDataReader data, string fieldName, T errorData)
        //{
        //    T _result = errorData;
        //    if (data != null && !string.IsNullOrEmpty(fieldName))
        //    {
        //        object _value = data[fieldName];
        //        if (!Convert.IsDBNull(_value))
        //        {
        //            _result = (T)Convert.ChangeType(_value, typeof(T));
        //        }
        //    }
        //    return _result;
        //}
        //#endregion
    }
}
